package com.hxzy.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxzy.common.constants.MarketConstants;
import com.hxzy.common.enums.AccountTypeEnum;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.exception.ServiceException;
import com.hxzy.common.resp.R;
import com.hxzy.common.util.MarketThreadLocalUtil;
import com.hxzy.common.util.PwdExecuteFactory;
import com.hxzy.controller.admin.employee.req.*;
import com.hxzy.controller.admin.employee.resp.EmployeeResp;
import com.hxzy.controller.admin.login.req.AdminLoginReq;
import com.hxzy.controller.admin.login.resp.AdminLoginResp;
import com.hxzy.entity.Employee;
import com.hxzy.mapstruct.EmployeeMapStruct;
import com.hxzy.service.EmployeeService;
import com.hxzy.mapper.EmployeeMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
* @author admin
* @description 针对表【employee(后台管理员表)】的数据库操作Service实现
* @createDate 2024-02-21 11:30:41
*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee>
    implements EmployeeService{

    @Autowired
    private PwdExecuteFactory  pwdExecuteFactory;

    @Override
    public AdminLoginResp login(AdminLoginReq req) {
        //1、根据用户名查询信息
        Employee  db=this.baseMapper.searchByLoginName(req.getLoginName());
        if(Objects.isNull(db)){
            throw new ServiceException(AckCode.LOGIN_ACCOUNT_PASSWORD_ERROR);
        }

//        //2、根据返回结果判断密码是否正确
//        if(!BCrypt.checkpw(req.getLoginPwd(),   db.getLoginPwd())){
//            throw new ServiceException(AckCode.LOGIN_ACCOUNT_PASSWORD_ERROR);
//        }
        this.pwdExecuteFactory.execute(req.getLoginPwd(),db.getLoginPwd(),db.getId(), AccountTypeEnum.ADMIN);

        //3、判断账户状态
        if(MarketConstants.ACCOUT_DISABLE.equals(db.getStatus())){
            throw new ServiceException(AckCode.DEVICE_BANNED);
        }

        //4、组装自定义对象
        AdminLoginResp   loginResp=new AdminLoginResp();
        loginResp.setId(db.getId());
        loginResp.setName(db.getLoginName());
        loginResp.setRoot(Long.parseLong( db.getRoot()));
        loginResp.setAvatar(db.getAvatar());
        loginResp.setPermissions(MarketConstants.ACCOUNT_ADMIN_TYPE);

        return loginResp;
    }

    @Override
    public List<EmployeeResp> search(EmployeeSearchReq req) {
        return this.baseMapper.search(req);
    }

    /**
     * 新增员工
     * @param req
     * @return
     */
    @Override
    public boolean addData(EmployeeAddReq req) {
        if(!req.getLoginPwd().equals(req.getLoginPwdConfirm())){
            throw new ServiceException(AckCode.SET_PASSWORD_INVALID);
        }

        //判断账户是否被使用了 select count(0) from employee where login_name=?
        if(this.accountExists(req.getLoginName())){
            throw new ServiceException(AckCode.EXISTS_VALUE_ACCOUNT);
        }

        //复制数据到实体类
        //Employee   employee=new Employee();
        //使用spring给我们对象copy操作(比较好用，但是网上说性能比较差)
        //BeanUtils.copyProperties(req,employee);

        //网上的解决方案使用 MapStruct来解决
        Employee employee = EmployeeMapStruct.INSTANCE.convert(req);
        //更改密码加密
        employee.setLoginPwd(BCrypt.hashpw(employee.getLoginPwd()));
        //不是超级管理员
        employee.setRoot(MarketConstants.ACCOUT_ENABLE);
        employee.setCreateTime(new Date());
        employee.setCreateBy(  MarketThreadLocalUtil.ADMIN_THREAD_LOCAL.get().getName());

        return this.save(employee);
    }

    /**
     * 判断账户是否被使用
     * @param account
     * @return
     */
    @Override
    public boolean accountExists(String account) {
        //判断账户是否被使用了 select count(0) from employee where login_name=?
        LambdaQueryWrapper<Employee>   wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getLoginName,account);
        return this.count(wrapper)>0;
    }

    /**
     * 更新数据
     * @param req
     * @return
     */
    @Override
    public boolean updateData(EmployeeEditReq req) {
        //先查询数据库，数据在不在
        Employee db = this.getById(req.getId());
        if(Objects.isNull(db)){
            throw new ServiceException(AckCode.NOT_FOUND_DATA);
        }

        db.setGender(req.getGender());
        db.setAvatar(req.getAvatar());

        //超级管理员
        if(req instanceof EmployeeSuperManEditReq) {
            EmployeeSuperManEditReq  superManEditReq= (EmployeeSuperManEditReq) req;
            if (!superManEditReq.getLoginPwd().equals(superManEditReq.getLoginPwdConfirm())) {
                throw new ServiceException(AckCode.SET_PASSWORD_INVALID);
            }

            db.setStatus(superManEditReq.getStatus());
            db.setLoginPwd( BCrypt.hashpw(superManEditReq.getLoginPwd()));
        }

        db.setUpdateTime(new Date());
        db.setUpdateBy(MarketThreadLocalUtil.ADMIN_THREAD_LOCAL.get().getName());

        return this.updateById(db);
    }

    /**
     * 更改账户状态
     * @param req
     * @return
     */
    @Override
    public boolean changeStatus(EmployeeStatusReq req) {
        if(req.getId().equals(MarketConstants.ACCOUNT_ROOT)){
            throw new ServiceException(AckCode.PERMISSION_NOT_ACCESS);
        }

        Employee db = this.getById(req.getId());
        if(Objects.isNull(db)){
            throw new ServiceException(AckCode.NOT_FOUND_DATA);
        }

        db.setStatus(req.getStatus());
        db.setUpdateTime(new Date());
        db.setUpdateBy(MarketThreadLocalUtil.ADMIN_THREAD_LOCAL.get().getName());

        return this.updateById(db);
    }

    @Override
    public List<EmployeeResp> exportExcel(EmployeeExportIdsReq req) {
        Long[] ids = req.getIds();

        return this.baseMapper.exportExcel(ids);
    }


}




